#ifndef _AGENCY_HPP_
#define	_AGENCY_HPP_

/*******************************************************************************
 ** Name: agency.hpp                                                          **
 ** Description:                                                              **
 **                                                                           **
 ** Open Source Initiative (OSI) Approved 2-clause BSD License                             **
 **                                                                           **
 **  Copyright (c) 2009-2010 Barry "Gian" James  <bjames@munixos.net>         **
 **  All rights reserved.                                                     **
 **                                                                           **
 **  Redistribution and use in source and binary forms, with or without       **
 **  modification, are permitted provided that the following conditions are   **
 **  met:                                                                     **
 **                                                                           **
 **  * Redistributions of source code must retain the above copyright notice, **
 **    this list of conditions and the following disclaimer.                  **
 **  * Redistributions in binary form must reproduce the above copyright      **
 **    notice, this list of conditions and the following disclaimer in the    **
 **    documentation and/or other materials provided with the distribution.   **
 **                                                                           **
 **  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS      **
 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED **
 ** TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A           **
 ** PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT        **
 ** HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    **
 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED  **
 ** TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR    **
 ** PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    **
 ** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING      **
 ** NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS        **
 ** SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              **
 **                                                                           **
 ******************************************************************************/
// Created on March 17, 2010, 8:18 PM
// Modified $Date: 2011-10-22 02:09:07 +0000 (Sat, 22 Oct 2011) $ by $Author: gian.james $
#define Agency_hpp_ID   "$Id: agency.hpp 146 2011-10-22 02:09:07Z gian.james $"

#include <odb/core.hxx>
#include <boost/intrusive/list.hpp>
#include <falcon/engine.h>
#include <string>
//#include "common.hpp"
//#include "character.hpp"

#define DEFAULT_AGENCY_CP   38

// The greatest inspiration for this level of agency detail comes from
// Spycraft v1.0 Agency manual OGL content.  Pick it up if you don't
// own it and incorporate it into your Spycraft 2.0 game.

namespace agency
{

//! The visibility level of the agency.
enum class visibility {
    cryptic, secretive, hitmiss, general, common
};

// TODO This should probably be in a world file somewhere
// TODO This should probably just be removed ~gian
enum class region {
    africa, asia, easteu, westeu, mideast, namerica, samerica, camerica
};

//! area of influence
//! agents get a bonus when operating/rolling against this sphere
enum class influence {
    business, law, military, judicial, govt, cultural, crime
};

//! influence quality
enum class quality {
    inferior, poor, average, good, excellent
};

//! How prepared does the agency make it's new field agents?
//! this can either give extra training points at char creation/joining
//! or offer specialized training players spend points to get
//! The number value is the agency CP cost.
enum class preparation {
    none, ojt=0x05, orientation=0x0F, academy=0x10
};

//! how extensive is the training at this agency
//! this training level determines the highest training course available
enum class training {
    seminar, outsourced, offsite, campus
};

//! max level of specialist able to render aid in the field
enum class specialist {
    amateur, competent, trained, skilled, expert
};

//! the agency's tolerance for its agents commiting crime
//! maybe this will effect the agency's reputation?
enum class tolerance {
    zero,           //!< zero-tolerance for crimes
    threestrikes,   //!< three strikes and yer out
    blindeye,       //!< you haven't broken a law until you get caught
    endsmeans       //!< ends justifies the means. do what you must.
};

//! How well does the agency value it's operatives?
enum class agentvalue {
    burn,       //!< the agency is just out to burn you
    unknown,    //!< if you get caught, we don't know you
    strings,    //!< will pull strings to help you if you get caught
    asset       //!< agents are highly-valued assets
};

//! Some gear requires the appropriate license
enum class licensure {
    none,       //!< no license. vigilante group.
    law,        //!< law enforcement
    federal,    //!< federal agency
    military    //!< military
};

//! what assets are at the agency's disposal?
enum class assets {
	AdvGarage = 0x000001,
	AdvLab = 0x000002,
	Airstrip = 0x000004,
	Armory = 0x000008,
	Classroom = 0x000010,
	CloneLab = 0x000020,
	COMSEC = 0x000040,
	Dojo = 0x000080,
	FiringRange = 0x000100,
	Harbor = 0x000200,
	Hospital = 0x000400,
	HotLab = 0x000800,
	LawOffice = 0x001000,
	MediaStudio = 0x002000,
	MilitaryDepot = 0x004000,
	MotorPool = 0x008000,
	Prison = 0x010000,
	RecordsOffice = 0x020000,
	Satellites = 0x040000,
	TrainingGround = 0x080000
};


//! the flavor/style of the agency
enum class methodology {
    insurection,    //!< focused on foreign govt instability
    infiltration,   //!< focused on b&e
    investigation,  //!< focused on investigating <whatever>
    appropriation,  //!< um, stealing :)
    wetwork,        //!< black ops, assassination
    paramilitary,   //!< military-style operations
    coverup         //!< false info dissemination, covering tracks, hiding secret
};

enum class origin {
    secret,         //!< origin (maybe) lost in mists of time
    founding,       //!< around time of founding of US
    ww1,            //!< (1910-1925)
    ww2,            //!< (1930-1945)
    redscare,       //!< (1950-1960)
    coldwar,        //!< (1960-1980)
    glastnost,      //!< (1980-1990) "tear down that wall"
    dotcom,         //!< (1990-2000) dot.com era
    terror          //!< (2000-present) war on terror
};

enum class deptnum
{
	Unassigned,S1,S2,S3,S4,S5,S6,S7
};

enum class stated_intent
{
	advising,
	apprehension,
	control,
	collection,
	combat,
	defense,
	freedom,
	investigation,
	justice,
	observation,
	peace,
	profit,
	protection,
	research,
	security,
	science,
	stability,
	support,
	training
};

enum class forte
{
	Unbreakable,		// +2 bonus fort save
	Unflappable,		// +2 bonus will save
	Uncanny,			// +2 bonus reflex save
	MasterStudents,		// +2 bonus academics check
	MasterCharmers,		// +2 bonus disposition/seduction
	MasterManipulators,	// +2 bonus blackmail/coercion
	MasterInterrogators,// +2 bonus interrogation
	MasterBrainwashers,	// +2 bonus brainwashing
	MasterTormentors,	// +2 bonus harassment
	MasterHackers,		// +2 bonus computers/electronics check
	MasterTrackers,		// +2 bonus search/surveillance
	MasterMotorists,	// +2 bonus maneuver or mechanic check
	MasterTricksters,	// +2 bonus bluff/disguise check
	MasterTravelers,	// +2 bonus language
	MasterDiplomats,	// +2 bureaucracy/diplomacy check
	MasterCryptographers,	// +2 crypto/forgery check
	MasterDetectives	// +2 gather info/surveillance check
};

extern std::string	dept[];

}   /* namespace agency */


//! Each agency has a sphere of influence
struct AgencyInfluence
{

};
//struct AgencyInfluence
//{
//    agency::influence   influence;
//    agency::quality     quality;
//    agency::region      region;
//};

//! Support for custom naming of rank structure in your agency
struct RankStructure
{
    std::string    rank;
    int             lvl;
};

//! @struct AgencyRoster
//! @brief structure to hold the agency's roster of personnel
struct AgencyRoster : public boost::intrusive::list_base_hook<>
{
	std::string		name;
	int				lvl;
	std::string		profession;
	agency::deptnum dept;
	bool			bOnline;
};

class Character;
//! @class Agency
//! @brief The field operative's employer
#pragma db object table("faction")
class Agency {
public:
    explicit Agency(std::string);
    Agency(const Agency& orig);
    ~Agency();
    Agency();

    static std::string StdFrenchRank(int r);
    static std::string StdMilRanks(int r);
    static std::string StdMarineRanks(int r);
    static std::string StdGovtRanks(int r);

    void	AgentLogin(std::string n);
    void	AgentLogout(std::string n);
    void	AddNewAgent(Character & c);	// add to agency
    void	RemoveAgent(Character & c);
    void	PromoteAgent(Character &c);
    void	DemoteAgent(Character &c);

    // Setters/Getters
    std::string &	Name() { return name; }
    agency::visibility & Visibility() { return vis; }
    int &			AgentMembers() { return memberAgent; }
    int &			HandlerMembers() { return memberHandler; }
    int &			ControlMembers() { return memberControl; }
    long &			Funds() { return funds; }
    agency::region & Region() { return homeregion; }
    std::string &	Cover() { return cover; }
    agency::stated_intent &	PublicIntent() { return pubintent; }
    agency::training &	Training() { return training; }
    agency::specialist & Specialists() { return specialists; }
    agency::forte &	Forte() { return forte; }
    long &			Assets() { return assets; }
    entity_t		ID() { return idfaction; }
    agency::origin &	Origin() { return origin; }

private:
    friend class odb::access;

#pragma db id auto
    entity_t		idfaction;
    std::string    name;			//!< name of the faction
    entity_t		idtools;
    std::string		owner_type;
    entity_t		idpc;
    entity_t		idnpc;
    std::string		desc;
    entity_t		idranks;
    entity_t		idagenda;
    entity_t		idawareness;
    entity_t		idhome_office;
    entity_t		idlicense;
    entity_t		idpublic_agenda;
    entity_t		idorigins;
    entity_t		idsphere;
    entity_t		idtraining;
    agency::visibility      vis;
    int				memberAgent;	//!< # of member agents
    int				memberHandler;
    int				memberControl;
    long            funds;
    agency::region  homeregion;
    std::string    cover;  //!< this is the cover story/business of the agency
    // FIXME this needs to be converted to work with ODB ORM
    std::string    ranks[20];
    agency::stated_intent		pubintent;
       //!< agency's private goal(s) [maybe not known to agents]
    boost::intrusive::list<AgencyRoster>	roster;
    agency::training training;
    agency::specialist specialists;
    agency::forte	forte;
    long			assets;
    agency::origin	origin;

};

/// The Falcon object carrier or wrapper
class FAgency : public Falcon::CoreObject
{
	Agency	data;

public:

};

#endif	/* _AGENCY_HPP_ */

